package http.tool;

import java.io.FileInputStream ;
import java.io.FileNotFoundException ;
import java.io.IOException ;
import java.io.InputStream ;
import java.security.KeyManagementException ;
import java.security.KeyStore ;
import java.security.KeyStoreException ;
import java.security.NoSuchAlgorithmException ;
import java.security.UnrecoverableKeyException ;
import java.security.cert.CertificateException ;
import java.security.cert.X509Certificate ;
import java.util.LinkedHashMap ;
import java.util.LinkedList ;
import java.util.List ;
import java.util.Map ;

import javax.net.ssl.KeyManager ;
import javax.net.ssl.KeyManagerFactory ;
import javax.net.ssl.SSLContext ;
import javax.net.ssl.TrustManager ;
import javax.net.ssl.TrustManagerFactory ;
import javax.net.ssl.X509TrustManager ;

import org.apache.http.HttpEntity ;
import org.apache.http.NameValuePair ;
import org.apache.http.conn.ssl.SSLContexts ;
import org.apache.http.entity.mime.FormBodyPart ;
import org.apache.http.entity.mime.HttpMultipartMode ;
import org.apache.http.entity.mime.MultipartEntityBuilder ;
import org.apache.http.message.BasicNameValuePair ;

/**
 * Description:关于请求的一些帮助类	
 * @author 80002165
 * @date 2016年12月13日 上午8:39:36
 */
public class RequestTool {
    /**
     * 验证请求参数是否合法null和空判断
     * @param param
     * @return
     * @author 80002165
     * @date 2016年12月13日 上午8:42:23
     */
    public static boolean checkMapParam(Map<String,Object> param){
        if(param == null || param.isEmpty())
            return false ;
        return true ;
    }
    
    /**
     * 将参数转换为get请求的参数格式 ?name=value&name=value
     * @param param
     * @return
     * @author 80002165
     * @date 2016年12月13日 上午8:40:13
     */
    public static String toGETParam(Map<String,Object> param){
        if(!checkMapParam(param)) return null ;
        StringBuffer urlParam = new StringBuffer("?") ;
        for(String paramName : param.keySet()){
            urlParam.append(paramName+"="+param.get(paramName).toString()+"&") ;
        }
        return urlParam.toString().substring(0, urlParam.toString().length()-1) ;
    }
    
    /**
     * 将参数转换为get请求的rest风格参数格式 /value1/value2
     * @param param
     * @return
     * @author 80002165
     * @date 2016年12月13日 上午8:40:13
     */
    public static String toGETParam_REST(LinkedHashMap<String,Object> param){
        if(!checkMapParam(param)) return null ;
        StringBuffer urlParam = new StringBuffer() ;
        for(String paramName : param.keySet()){
            urlParam.append("/"+param.get(paramName).toString()) ;
        }
        return urlParam.toString() ;
    }
    
    /**
     * post请求传参格式
     * @param param
     * @return
     * @author 80002165
     * @date 2016年12月13日 上午8:49:06
     */
    public static List<NameValuePair> toPOSTParam(Map<String,Object> param){
        if(!checkMapParam(param)) return null ;
        List<NameValuePair> nvp = new LinkedList<NameValuePair>() ;
        for(String paramName : param.keySet()){
            nvp.add(new BasicNameValuePair(paramName, param.get(paramName).toString())) ;
        }
        return nvp ;
    }
    
    /**
     * post请求的表单参数
     * @param formParts
     * @return
     * @author 80002165
     * @date 2016年12月13日 上午8:58:07
     */
    public static HttpEntity toPOSTParam_FORM(List<FormBodyPart> formParts){
        if(formParts == null || formParts.isEmpty()) return null ;
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        entityBuilder = entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        for (FormBodyPart formPart : formParts) {
            entityBuilder = entityBuilder.addPart(formPart.getName(), formPart.getBody());
        }
        return entityBuilder.build() ;
    }
    
    private static String defaultProtocol(String protocol){
        if (protocol == null || protocol.trim().equals(""))
            protocol = "SSL" ;
        return protocol ;
    }
    
    /**
     * https跳过验证
     * @param protocol
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     * @author 80002165
     * @date 2016年12月13日 上午9:28:42
     */
    public static SSLContext  sslContext_alone (String protocol) throws NoSuchAlgorithmException, KeyManagementException {
        protocol = defaultProtocol(protocol) ;
        SSLContext ssl = SSLContext.getInstance(protocol) ;
        ssl.init(null, new X509TrustManager[]{new X509TrustManager() {
            X509Certificate[] client = null;
            X509Certificate[] server = null;
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0]; 
            }
            
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                server = chain ; 
            }
            
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                client = chain;
            }
        }}, null);
        return ssl ;
    }
    
    /**
     * https双向验证
     * @param protocol https用到的协议
     * @param keyPath证书的路径
     * @param keyPwd证书的密码
     * @param keyType证书的的算法
     * @param trustPath
     * @param trustPwd
     * @param turstType
     * @return
     * @author 80002165
     * @throws NoSuchAlgorithmException 
     * @throws KeyStoreException 
     * @throws IOException 
     * @throws FileNotFoundException 
     * @throws CertificateException 
     * @throws UnrecoverableKeyException 
     * @throws KeyManagementException 
     * @date 2016年12月13日 下午7:03:26
     */
    public static SSLContext  sslContext_double(String protocol, String keyPath, String keyPwd, String keyType, String trustPath, String trustPwd, String turstType) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException{
        protocol = defaultProtocol(protocol) ;
        SSLContext ssl = SSLContext.getInstance(protocol) ;
        KeyStore keyStore = KeyStore.getInstance(keyType) ;
        keyStore.load(new FileInputStream(keyPath), keyPwd.toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) ;
        kmf.init(keyStore, keyPwd.toCharArray());
        KeyManager[] kms = kmf.getKeyManagers() ;
       
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()) ;
        trustStore.load(new FileInputStream(trustPath), trustPwd.toCharArray());
        TrustManagerFactory trustmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) ;
        trustmf.init(trustStore); 
        TrustManager[] tms = trustmf.getTrustManagers() ;
        
        ssl.init(kms, tms, null);
        
        return ssl ;
    }
    
}
